package net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.Socket;

import message.Packet;

/**
 * TODO: cambio di impostazione della rete -> notifica stato attuale OFFLINE ->
 * cambio -> ONLINE
 * **/

abstract class Sender implements Runnable {
	private String packetRappresentation;
	private Socket socket;

	Sender(Packet packet) {
		this.packetRappresentation = packet.toXML();
		this.socket = this.setUpSocket(OlivawPortsClient.getOutputPort());
	}

	private Socket setUpSocket(int outputPort) {
		Socket socket = null;
		while (true) {
			try {
				socket = new Socket(ServerConnection.getAddress(), outputPort);
				OlivawPortsClient.setOutputPort(outputPort);
				System.out.println(socket.getPort());
				System.out.println(socket.getLocalPort());
				return socket;
			} catch (ConnectException e){
				this.handleServerUnreachable();
				e.printStackTrace();
			} catch (IOException e) {
				outputPort++;
			}
		}
	}

	@Override
	public void run() {
		try {
			int response = this._run();
			if (response == Packet.UNKNOWN_PACKET)
				this.handleInvalidPacket();
			else
				this.handleResponse(response);
		} catch (ConnectException e) {
			this.handleServerUnreachable();
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private int _run() throws IOException {
		PrintWriter out = null;
		BufferedReader in = null;
		out = new PrintWriter(socket.getOutputStream(), true);
		in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

		out.println(this.packetRappresentation);
		int response = in.read();
		System.out.println(response);

		out.close();
		in.close();
		socket.close();

		return response;
	}

	abstract void handleResponse(int response);

	private void handleInvalidPacket() {
		System.out.println("Invalid Packet");
	}
	
	private void handleServerUnreachable(){
		System.out.println("Server Unreachable");
		System.exit(0);
	}
}
